package rpa

import (
	"context"
	"database/sql"
	"errors"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/common/utils"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/common/utils/jwt"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/rpa"
	pb "git.mycaigou.com/gfyx/micro-gfyx-oppty-service/proto/micro_gfyx_oppty_service_proto/micro-gfyx-oppty-service/rpa"
	"git.myscrm.cn/golang/stark/v4"
	"github.com/google/uuid"
	"google.golang.org/grpc/metadata"
	"gorm.io/gorm"
	"time"
)

/**
 * @Author: xiuliu
 * @Description:
 * @File:  rpa_service
 * @Version: 1.0.0
 * @Date: 2023/10/30 17:05
 */

type RpaService struct {
	rpaRepository rpa.RpaRepositoryIface
}

func NewRpaService(rpaRepository rpa.RpaRepositoryIface) RpaServiceIface {
	return &RpaService{
		rpaRepository: rpaRepository,
	}
}

//保存RPA配置信息
func (r *RpaService) SaveData(ctx context.Context, request *pb.SaveRpaConfigRequest) (string, error) {
	//校验配置是否已存在，暂不考虑配置修改,有修改需求可以发sql
	condition := map[string]interface{}{}
	_, err := r.rpaRepository.GetInfo(ctx, condition)
	if err != nil && err == gorm.ErrRecordNotFound {
		reqData := request.Data
		currentTime := time.Now()
		data := rpa.RpaConfig{
			UserMobile:  request.Data.UserMobile,
			Version:     reqData.Version,
			RpaVersion:  reqData.RpaVersion,
			MachineCode: reqData.MachineCode,
			StartTime: sql.NullTime{
				Time:  time.Time{},
				Valid: false,
			},
			EndTime: sql.NullTime{
				Time:  time.Time{},
				Valid: false,
			},
			CreatedOn:  currentTime,
			ModifiedOn: currentTime,
		}
		//生成secret key
		data.SecretKey = uuid.New().String()

		flag, err := r.rpaRepository.InsertData(ctx, &data)
		if err != nil {
			stark.Logger.Errorf(ctx, "保存RPA配置信息失败,err:", err)
			return "", err
		}
		if flag == false {
			return "", errors.New("配置信息保存失败")
		}
		return data.SecretKey, nil
	} else if err != nil {
		stark.Logger.Errorf(ctx, "获取RPA配置信息失败,err:", err)
		return "", err
	} else {
		return "", errors.New("配置信息已存在，请勿重复初始化")
	}
}

//获取RPA配置信息
func (r *RpaService) GetInfo(ctx context.Context, request *pb.GetRpaConfigInfoRequest) (*pb.GetRpaConfigResponse, error) {
	condition := map[string]interface{}{}
	if request.UserMobile != "" {
		condition["user_mobile"] = request.UserMobile
	}
	if request.MachineCode != "" {
		condition["machine_code"] = request.MachineCode
	}
	if request.Version != "" {
		condition["version"] = request.Version
	}
	if request.RpaVersion != "" {
		condition["rpa_version"] = request.RpaVersion
	}
	data, err := r.rpaRepository.GetInfo(ctx, condition)
	if err != nil && err == gorm.ErrRecordNotFound {
		return nil, nil
	}

	resp := &pb.GetRpaConfigResponse{}
	if data != nil {
		rpaconfig := &pb.RpaConfig{
			UserMobile:  data.UserMobile,
			SecrectKey:  data.SecretKey,
			Version:     data.Version,
			RpaVersion:  data.RpaVersion,
			MachineCode: data.MachineCode,
		}

		if data.StartTime.Time.IsZero() {
			rpaconfig.StartTime = ""
		} else {
			rpaconfig.StartTime = utils.TimeToString(data.StartTime.Time)
		}

		if data.EndTime.Time.IsZero() {

			rpaconfig.EndTime = ""
		} else {
			rpaconfig.EndTime = utils.TimeToString(data.EndTime.Time)
		}

		resp.Data = rpaconfig
	} else {
		resp.Data = nil
	}

	return resp, err
}

//rpa 启动验证
func (r *RpaService) RpaStart(ctx context.Context, request *pb.RpaStartRequest) (string, error) {
	condition := map[string]interface{}{}
	if request.UserMobile != "" {
		condition["user_mobile"] = request.UserMobile
	}
	if request.SecrectKey != "" {
		condition["secret_key"] = request.SecrectKey
	}
	//if request.MachineCode != "" {
	//	condition["machine_code"] = request.MachineCode
	//}
	if request.Version != "" {
		condition["version"] = request.Version
	}
	if request.RpaVersion != "" {
		condition["rpa_version"] = request.RpaVersion
	}
	data, err := r.rpaRepository.GetInfo(ctx, condition)
	if err != nil && err == gorm.ErrRecordNotFound {
		return "", errors.New("RPA配置信息不存在")
	} else if err != nil {
		stark.Logger.Errorf(ctx, "获取RPA配置信息错误", err.Error())
		return "", err
	}
	// 客户端第一次启动更新并绑定机器码
	if data.MachineCode != "" {
		if request.MachineCode != data.MachineCode {
			return "", errors.New("客户端未授权")
		}
	} else {
		if request.MachineCode != "" {
			data.MachineCode = request.MachineCode
			_, err := r.rpaRepository.UpdateData(ctx, data)
			if err != nil {
				stark.Logger.Errorf(ctx, "RPA配置信息客户端机器码更新失败", err.Error())
				return "", err
			}
		} else {
			return "", errors.New("客户端机器码不能为空")
		}
	}

	tenantCode := r.GetTenantCode(ctx)
	if tenantCode == "" {
		return "", errors.New("获取租户信息失败")
	}
	//生成token
	jwtToken, err := jwt.DefaultRpaJWT.GenerateRpaToken(tenantCode, data.UserMobile)
	if err != nil {
		stark.Logger.Errorf(ctx, "生成RPA 启动 token错误", err.Error())
		return "", err
	}
	startLog := &rpa.RpaStartLog{
		LoginTime: time.Now(),
		Token:     jwtToken,
		CreatedOn: time.Now(),
	}
	flag, err := r.rpaRepository.InsertStartLog(ctx, startLog)
	if err != nil {
		stark.Logger.Errorf(ctx, "保存登录日志错误", err.Error())
		return "", err
	}
	if flag == false {
		stark.Logger.Errorf(ctx, "保存登录日志失败")
		return "", errors.New("保存登录日志失败")
	}

	return jwtToken, nil
}

//获取登录信息
func (r *RpaService) GetRpaStartInfo(ctx context.Context, request *pb.GetRpaStartInfoRequest) (string, error) {
	condition := map[string]interface{}{}
	if request.Token != "" {
		condition["token"] = request.Token
	}

	startLog, err := r.rpaRepository.CheckRpaToken(ctx, condition)
	if err != nil && err != gorm.ErrRecordNotFound {
		return "", errors.New("启动信息不存在")
	} else if err != nil {
		return "", err
	}

	return startLog.Token, nil
}

func (r *RpaService) GetTenantCode(ctx context.Context) string {
	md, ok := metadata.FromIncomingContext(ctx)
	if !ok {
		return ""
	}

	v := md.Get("tenant_code")
	if len(v) <= 0 {
		return ""
	}

	return v[0]
}
